package org.ecloud;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;

import org.ecloud.zuul.filter.AccessFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

import com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.config.DefaultRateLimitKeyGenerator;
import com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.config.RateLimitKeyGenerator;
import com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.config.properties.RateLimitProperties;
import com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.config.repository.DefaultRateLimiterErrorHandler;
import com.marcosbarbero.cloud.autoconfigure.zuul.ratelimit.config.repository.RateLimiterErrorHandler;

/**
 * 网关服务-主类
 *
 * <pre>
 *  
 * project: ecloud-zuul
 * author: eddy
 * email: xqxyxchy@126.com
 * date: 2018年3月5日-下午9:04:04
 * rights: eddy
 * </pre>
 */
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication implements CommandLineRunner {

	private static Logger logger = LoggerFactory.getLogger(ZuulApplication.class);
	
	public static void main(String[] args) throws IOException {
		logger.info("Starting Zuul.");
		SpringApplication.run(ZuulApplication.class, args);
	}

	@Bean
	public AccessFilter accessFilter() {
		return new AccessFilter();
	}

	/**
     * Configures the Java client for Redis.
     * @return the Java Redis client object
     */
    @Bean
    public JedisConnectionFactory jedisConnectionFactory() {
        return new JedisConnectionFactory();
    }

    /**
     * Provides the central class of the Redis module for Redis interactions.
     * @return the Redis interaction class
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(jedisConnectionFactory());
        return redisTemplate;
    }
	
	@Bean
	public RateLimitKeyGenerator rateLimitKeyGenerator(final RateLimitProperties properties) {
		return new DefaultRateLimitKeyGenerator(properties) {
			@Override
			public String key(HttpServletRequest request, Route route, RateLimitProperties.Policy policy) {
				return super.key(request, route, policy) + ":" + request.getMethod();
			}
		};
	}

	@Bean
	public RateLimiterErrorHandler rateLimitErrorHandler() {
		return new DefaultRateLimiterErrorHandler() {
			@Override
			public void handleSaveError(String key, Exception e) {
				// custom code
				logger.error(e.getMessage(), e);
			}

			@Override
			public void handleFetchError(String key, Exception e) {
				// custom code
				logger.error(e.getMessage(), e);
			}

			@Override
			public void handleError(String msg, Exception e) {
				// custom code
				logger.error(e.getMessage(), e);
			}
		};
	}

	@Override
	public void run(String... args) throws Exception {
		logger.info("Started Zuul.");
	}

}
